package com.hurl.waguji.base;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Restrictions;

import com.hurl.library.http.HttpUtils;
import com.hurl.library.util.DateUtils;
import com.hurl.library.util.StringUtils;
import com.hurl.waguji.base.dao.HibernateDao;
import com.hurl.waguji.base.dao.HibernateService;
import com.hurl.waguji.persistence.DmJjrBO;
import com.hurl.waguji.persistence.JyrBO;

public class DateService {
	public static final Logger log = Logger.getLogger(DateService.class);
	
	public static void initTimeZone(){
		TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
	}
	
	public static Date endOfPreviousSeason(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		if(month>=Calendar.JANUARY && month<=Calendar.MARCH){
			c.set(Calendar.YEAR, c.get(Calendar.YEAR)-1);
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			c.set(Calendar.DAY_OF_MONTH, 31);
		}else if(month>=Calendar.APRIL && month<=Calendar.JUNE){
			c.set(Calendar.MONTH, Calendar.MARCH);
			c.set(Calendar.DAY_OF_MONTH, 31);
		}else if(month>=Calendar.JULY && month<=Calendar.SEPTEMBER){
			c.set(Calendar.MONTH, Calendar.JUNE);
			c.set(Calendar.DAY_OF_MONTH, 30);
		}else{
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			c.set(Calendar.DAY_OF_MONTH, 30);
		}
		return c.getTime();
	}
	public static Date endOfPreviousYear(Date date){
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DAY_OF_YEAR, 1);
		c.add(Calendar.DAY_OF_YEAR, -1);
		return c.getTime();
	}
	
	/**
	 * 根据服务器计算出最后交易时间
	 * @return
	 */
	public static Date getLastTradingTimeFromServer(){
		Calendar c = Calendar.getInstance();
		while(DateService.isWeekend(c) || DateService.isJJr(c.getTime())){
			c.add(Calendar.DATE, -1);
		}
		return c.getTime();
		
	}
	public static Date getLastTradingTimeFromWeb(){
		String url = "http://hq.sinajs.cn/list=sh000001";
		try {
			String html = HttpUtils.request(url);
			String content = StringUtils.substringBetween(html, "\"", "\"");
			if(StringUtils.isBlank(content)){
				throw new WagujiRuntimeException("获取最后交易时间失败！");
			}
			String[] parts = content.split(",");
			if(parts==null || parts.length<32){
				throw new WagujiRuntimeException("获取最后交易时间失败：数据格式不对，取不到最后交易时间!");
			}
			String rq = parts[30];
			String sj = parts[31];
			Date date = DateUtils.parseDate(rq+" "+sj, DateUtils.FORMAT_DATE_TIME);
			saveLastTradingDate(date);
			return date;
		} catch (Exception e) {
			throw new WagujiRuntimeException("获取最后交易时间失败！", e);
		}
	}
	private static void saveLastTradingDate(Date rq){
		HibernateDao dao = HibernateService.getDao();
		JyrBO bo = dao.get(JyrBO.class, rq);
		if(bo==null){
			bo = new JyrBO();
			bo.setJyr(rq);
			dao.save(bo);
			dao.flush();
			dao.clear();
		}
	}
	/**
	 * 判断是否为节假日
	 * @param time 要判断的日期
	 * @return 如果是节假日，返回true，否则返回false
	 */
	public static boolean isJJr(Date time){
		String timestr = DateUtils.formatDate(time, DateUtils.FORMAT_DATE);
		Date date = null;
		try {
			date = DateUtils.parseDate(timestr, DateUtils.FORMAT_DATE);
		} catch (ParseException e) {
			throw new WagujiRuntimeException("计算节假日时日期格式转换错误");
		}
		
		HibernateDao dao = HibernateService.getDao();
		
		int size = dao.createCriteria(DmJjrBO.class)
		.add(Restrictions.eq("flag", 'Y'))
		.add(Restrictions.le("jjrq", date))
		.add(Restrictions.ge("jjrz", date)).list().size();
		
		if(size==0){
			return false;
		}else{
			return true;
		}
	}
	
	/**
	 * 判断是否为周末（即周六或周日）
	 * @param date 要判断的日期
	 * @return 如果是股票周末，返回true，否则返回false
	 */
	public static boolean isWeekend(Calendar date){
		int weekday = date.get(Calendar.DAY_OF_WEEK);
		return weekday==Calendar.SATURDAY || weekday==Calendar.SUNDAY;
	}
	
	/**
	 * 判断否为股票交易时间（包含中午休市时间）
	 * @param time 要判断的某个时间
	 * @return 如果是股票交易时间，返回true，否则返回false
	 */
	public static boolean isInTrading(Date time){
			if(isJJr(time)){
				return false;
			}
			
			Calendar c = Calendar.getInstance();
			c.setTime(time);
			
			if(isWeekend(c)){
				return false;
			}
			
			int hour = c.get(Calendar.HOUR_OF_DAY);
			
			return hour>=9 && hour<15;
	}
	
	/**
	 * 判断某个时间是否为收盘以后的时间
	 * @param time
	 * @return 如果是收盘后时间则返回true，否则返回false。节假日，周末的任何时间都返回false。
	 */
	public static boolean isAfterTrading(Date time){
		return isAfterTrading(time,0);
	}

	public static boolean isNowAfterTradingTime(Date lastTradingTime){
		return isNowAfterTradingTime(lastTradingTime,0);
	}
	public static boolean isNowAfterTradingTime(Date lastTradingTime,int delayHour){
		Date now = DateService.getCurrentTimeFromServer();
		if(!isTheSameDay(now,lastTradingTime)){
			return false;
		}
		
		return isAfterTrading(now,delayHour);
	}
	/*
	 * 判断是两个日期是否为同一天
	 */
	private static boolean isTheSameDay(Date date1,Date date2){
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);
		return c1.get(Calendar.YEAR)==c2.get(Calendar.YEAR)
				&& c1.get(Calendar.MONTH)==c2.get(Calendar.MONTH)
				&& c1.get(Calendar.DAY_OF_MONTH)==c2.get(Calendar.DAY_OF_MONTH);
	}
	/**
	 * 判断某个时间是否为收盘以后的时间
	 * @param time
	 * @return 如果是收盘后时间则返回true，否则返回false。节假日，周末的任何时间都返回false。
	 */
	public static boolean isAfterTrading(Date time,int delayHour){
		if(isJJr(time)){
			return false;
		}
		
		Calendar c = Calendar.getInstance();
		c.setTime(time);
		
		if(isWeekend(c)){
			return false;
		}
		
		int hour = c.get(Calendar.HOUR_OF_DAY);
		return hour>=(15+delayHour);
	}
	public static Date getCurrentTimeFromWeb(){
		String url = "http://hq.sinajs.cn/list=sh000001";
		try {
			String html = HttpUtils.request(url);
			String content = StringUtils.substringBetween(html, "\"", "\"");
			if(StringUtils.isBlank(content)){
				throw new WagujiRuntimeException("获取最后交易时间失败！");
			}
			String[] parts = content.split(",");
			if(parts==null || parts.length<32){
				throw new WagujiRuntimeException("获取最后交易时间失败：数据格式不对，取不到最后交易时间!");
			}
			String rq = parts[30];
			String sj = parts[31];
			Date date = DateUtils.parseDate(rq+" "+sj, DateUtils.FORMAT_DATE_TIME);
			return date;
		} catch (Exception e) {
			throw new WagujiRuntimeException("获取最后交易时间失败！", e);
		}
	}
	/**
	 * 取得最近的一次股票交易时间
	 * @return 最近的一次股票交易时间
	 */
	public static Date getCurrentTimeFromServer(){
		return new Date();
	}/*
	public static boolean reportResult(SsJobReportBO bo){
		return bo!=null && bo.getResult();
	}*/
	/*public static SsJobReportBO readReport(HibernateDAO dao, String reportCode,Date rq){
		SsJobReportBO bo = new SsJobReportBO();
		bo.setReportCode(reportCode);
		bo.setRq(rq);
		dao.beginTransaction();
		List list = dao.createCriteria(SsJobReportBO.class)
			.add(Restrictions.eq("reportCode", reportCode))
			.add(Restrictions.eq("rq",rq)).list();
		if(list!=null && !list.isEmpty()){
			return (SsJobReportBO)list.get(list.size()-1);
		}
		return null;
		
	}
	public static void recordReport(String reportCode,Date rq,Date sj, boolean success){
		HibernateDAO dao = HibernateService.getDAO();
		SsJobReportBO bo = new SsJobReportBO();
		bo.setReportCode(reportCode);
		bo.setRq(rq);
		bo.setSj(sj);
		bo.setResult(success);
		dao.beginTransaction();
		dao.save(bo);
	}*/
}
